package rabbitmq

//
//import (
//	"fmt"
//	"github.com/streadway/amqp"
//	"log"
//	"sync"
//	_ "time"
//)
//
//// 定义全局变量,指针类型
////var mqConn *amqp.Connection
////var mqChan *amqp.Channel
//
//// 定义生产者接口
//type Producer interface {
//	MsgContent() string
//}
//
//// 定义接收者接口
//type Receiver interface {
//	Consumer([]byte) error
//}
//
//var chans map[string]amqp.Channel
//
//// 定义RabbitMQ对象
//type RabbitMQ struct {
//	MqAddr  string
//	MqPort  int
//	MqUser  string
//	MqPwd   string
//	MqVhost string
//
//	connection 		*amqp.Connection
//	chans 			[]*ChannelContext
//	QueueList    	[]QueueInfo
//
//	//connection *amqp.Connection
//	//channel    *amqp.Channel
//
//	//exqulist map[string]QueueInfo
//	//QueueName    string // 队列名称
//	//RoutingKey   string // key名称
//	//ExchangeName string // 交换机名称
//	//ExchangeType string // 交换机类型
//	//producerList []Producer
//	//receiverList []Receiver
//	//mainMQ       *MainMq
//	mu sync.RWMutex
//}
//
//
//type ChannelContext struct {
//	Exchange     string
//	ExchangeType string
//	RoutingKey   string
//	Reliable     bool
//	Durable      bool
//	ChannelId    string
//	Channel      *amqp.Channel
//}
//
////type MainMq struct {
////	connection *amqp.Connection
////	channs     map[string]QueueInfo
////}
//
//// 定义队列交换机对象
//type QueueInfo struct {
//	QueueName    string // 队列名称
//	RoutingKey   string // key值
//	ExchangeName string // 交换机名称
//}
////
////// 定义队列交换机对象
////type ExchangeInfo struct {
////	ExchangeName string // 交换机名称
////	ExchangeType string // 交换机类型
////}
//
//func (r *RabbitMQ) NewConnection() {
//	RabbitUrl := fmt.Sprintf("amqp://%s:%s@%s:%d/%s", r.MqUser, r.MqPwd, r.MqAddr, r.MqPort, r.MqVhost)
//	mqConn, err := amqp.Dial(RabbitUrl)
//
//	if err != nil {
//		RaiseException(err, "init mq connection failed！")
//	}
//	r.connection = mqConn // 赋值给RabbitMQ对象
//}
//
//func (r *RabbitMQ) NewChannels() {
//	RabbitUrl := fmt.Sprintf("amqp://%s:%s@%s:%d/%s", r.MqUser, r.MqPwd, r.MqAddr, r.MqPort, r.MqVhost)
//	mqConn, err := amqp.Dial(RabbitUrl)
//
//	if err != nil {
//		RaiseException(err, "init mq connection failed！")
//	}
//	r.connection = mqConn // 赋值给RabbitMQ对象
//}
//
//
//// 链接rabbitMQ
//func (r *RabbitMQ) Run(closeSig chan bool) {
//	var err error
//	RabbitUrl := fmt.Sprintf("amqp://%s:%s@%s:%d/%s", r.MqUser, r.MqPwd, r.MqAddr, r.MqPort, r.MqVhost)
//	mqConn, err = amqp.Dial(RabbitUrl)
//
//	if err != nil {
//		RaiseException(err, "MQ打开链接失败")
//	}
//
//	r.connection = mqConn // 赋值给RabbitMQ对象
//
//	mqChan, err = mqConn.Channel()
//
//	if err != nil {
//		RaiseException(err, "MQ打开管道失败")
//	}
//	// 创建交换机
//	for ex := 0; ex < len(r.ExchangeList); ex++ {
//		// 校验交换机是否存在，不存在则创建
//		err = r.channel.ExchangeDeclarePassive(
//			r.ExchangeList[ex].ExchangeName, //exchange name
//			r.ExchangeList[ex].ExchangeType, //exchange kind
//			true,                            //durable
//			false,                           //autodelete
//			false,
//			false,
//			nil)
//		if err != nil {
//			// 队列不存在,声明队列
//			// name:队列名称;durable:是否持久化,队列存盘,true服务重启后信息不会丢失,影响性能;autoDelete:是否自动删除;noWait:是否非阻塞,
//			// true为是,不等待RMQ返回信息;args:参数,传nil即可;exclusive:是否设置排他
//			err = mqChan.ExchangeDeclare(
//				r.ExchangeList[ex].ExchangeName, //exchange name
//				r.ExchangeList[ex].ExchangeType, //exchange kind
//				true,                            //durable
//				false,                           //autodelete
//				false,
//				false,
//				nil,
//			)
//			failOnError(err, fmt.Sprint("MQ注册交换机[%s,%s]失败", r.ExchangeList[ex].ExchangeName, r.ExchangeList[ex].ExchangeType))
//
//		}
//	}
//
//	// 创建队列
//	for qu := 0; qu < len(r.QueueList); qu++ {
//		// 用于检查队列是否存在,已经存在不需要重复声明
//		_, err = r.channel.QueueDeclarePassive(
//			r.QueueList[qu].QueueName,
//			false, //durable
//			false, //delete when unused
//			true,  //exclusive
//			false, //no-wait
//			nil,   //arguments
//		)
//		if err != nil {
//			// 队列不存在,声明队列
//			// name:队列名称;durable:是否持久化,队列存盘,true服务重启后信息不会丢失,影响性能;autoDelete:是否自动删除;noWait:是否非阻塞,
//			// true为是,不等待RMQ返回信息;args:参数,传nil即可;exclusive:是否设置排他
//			_, err := r.channel.QueueDeclare(
//				r.QueueList[qu].QueueName,
//				false, //durable
//				false, //delete when unused
//				true,  //exclusive
//				false, //no-wait
//				nil,   //arguments
//			)
//			failOnError(err, fmt.Sprint("MQ注册队列[%s]失败", r.QueueList[qu].QueueName))
//			if err != nil {
//				continue
//			}
//		}
//
//		err = r.channel.QueueBind(
//			r.QueueList[qu].QueueName,
//			r.QueueList[qu].RoutingKey,
//			r.QueueList[qu].ExchangeName,
//			false,
//			nil,
//		)
//		failOnError(err, fmt.Sprint("MQ队列[%s]创建监听[%s:%s]失败", r.QueueList[qu].QueueName, r.QueueList[qu].ExchangeName, r.QueueList[qu].RoutingKey))
//		if err != nil {
//			continue
//		}
//		//r.exqulist[r.QueueList[qu].ExchangeName] = r.QueueList[qu]
//	}
//}
//
//// 发送消息到交换机
//func (r *RabbitMQ) SendintoQueue(exchange string, routekey string, msg interface{}) error {
//
//	err := r.channel.Publish(
//		exchange, //exchange
//		routekey, //routing key
//		false,
//		false,
//		amqp.Publishing{
//			ContentType: "text/plain",
//			Body:        msg.([]byte),
//		})
//
//	log.Printf(" [x] Sent %s", msg)
//
//	failOnError(err, "Failed to publish a message")
//
//	return err
//}
//
//// 从队列获取消息
//func (r *RabbitMQ) BindOneQueue(queueName string, routekey string, msg interface{}) error {
//	err := r.channel.Qos(1, 0, true)
//	msgList, err := r.channel.Consume(queueName, "", false, false, false, false, nil)
//	if err != nil {
//		fmt.Printf("获取消费通道异常:%s \n", err)
//		return
//	}
//	for msg := range msgList {
//		// 处理数据
//		err := receiver.Consumer(msg.Body)
//		if err != nil {
//			err = msg.Ack(true)
//			if err != nil {
//				fmt.Printf("确认消息未完成异常:%s \n", err)
//				return
//			}
//		} else {
//			// 确认消息,必须为false
//			err = msg.Ack(false)
//			if err != nil {
//				fmt.Printf("确认消息完成异常:%s \n", err)
//				return
//			}
//			return
//		}
//	}
//}
//
////// 启动RabbitMQ客户端,并初始化
////func (r *RabbitMQ) Start() {
////	// 开启监听生产者发送任务
////	for _, producer := range r.producerList {
////		go r.listenProducer(producer)
////	}
////	// 开启监听接收者接收任务
////	for _, receiver := range r.receiverList {
////		go r.listenReceiver(receiver)
////	}
////	time.Sleep(1 * time.Second)
////}
//
//// 注册发送指定队列指定路由的生产者
//func (r *RabbitMQ) RegisterProducer(producer Producer) {
//	r.producerList = append(r.producerList, producer)
//}
//
//// 发送任务
//func (r *RabbitMQ) listenProducer(producer Producer) {
//	// 验证链接是否正常,否则重新链接
//	if r.channel == nil {
//		r.mqConnect()
//	}
//	// 用于检查队列是否存在,已经存在不需要重复声明
//	_, err := r.channel.QueueDeclarePassive(r.QueueName, true, false, false, true, nil)
//	if err != nil {
//		// 队列不存在,声明队列
//		// name:队列名称;durable:是否持久化,队列存盘,true服务重启后信息不会丢失,影响性能;autoDelete:是否自动删除;noWait:是否非阻塞,
//		// true为是,不等待RMQ返回信息;args:参数,传nil即可;exclusive:是否设置排他
//		_, err = r.channel.QueueDeclare(r.QueueName, true, false, false, true, nil)
//		if err != nil {
//			fmt.Printf("MQ注册队列失败:%s \n", err)
//			return
//		}
//	}
//	// 队列绑定
//	err = r.channel.QueueBind(r.QueueName, r.RoutingKey, r.ExchangeName, true, nil)
//	if err != nil {
//		fmt.Printf("MQ绑定队列失败:%s \n", err)
//		return
//	}
//	// 用于检查交换机是否存在,已经存在不需要重复声明
//	err = r.channel.ExchangeDeclarePassive(r.ExchangeName, r.ExchangeType, true, false, false, true, nil)
//	if err != nil {
//		// 注册交换机
//		// name:交换机名称,kind:交换机类型,durable:是否持久化,队列存盘,true服务重启后信息不会丢失,影响性能;autoDelete:是否自动删除;
//		// noWait:是否非阻塞, true为是,不等待RMQ返回信息;args:参数,传nil即可; internal:是否为内部
//		err = r.channel.ExchangeDeclare(r.ExchangeName, r.ExchangeType, true, false, false, true, nil)
//		if err != nil {
//			fmt.Printf("MQ注册交换机失败:%s \n", err)
//			return
//		}
//	}
//	// 发送任务消息
//	err = r.channel.Publish(r.ExchangeName, r.RoutingKey, false, false, amqp.Publishing{
//		ContentType: "text/plain",
//		Body:        []byte(producer.MsgContent()),
//	})
//	if err != nil {
//		fmt.Printf("MQ任务发送失败:%s \n", err)
//		return
//	}
//}
//
//// 注册接收指定队列指定路由的数据接收者
//func (r *RabbitMQ) RegisterReceiver(receiver Receiver) {
//	r.mu.Lock()
//	r.receiverList = append(r.receiverList, receiver)
//	r.mu.Unlock()
//}
//
//// 监听接收者接收任务
//func (r *RabbitMQ) listenReceiver(receiver Receiver) {
//	// 处理结束关闭链接
//	defer r.mqClose()
//	// 验证链接是否正常
//	if r.channel == nil {
//		r.mqConnect()
//	}
//	// 用于检查队列是否存在,已经存在不需要重复声明
//	_, err := r.channel.QueueDeclarePassive(r.QueueName, true, false, false, true, nil)
//	if err != nil {
//		// 队列不存在,声明队列
//		// name:队列名称;durable:是否持久化,队列存盘,true服务重启后信息不会丢失,影响性能;autoDelete:是否自动删除;noWait:是否非阻塞,
//		// true为是,不等待RMQ返回信息;args:参数,传nil即可;exclusive:是否设置排他
//		_, err = r.channel.QueueDeclare(r.QueueName, true, false, false, true, nil)
//		if err != nil {
//			fmt.Printf("MQ注册队列失败:%s \n", err)
//			return
//		}
//	}
//	// 绑定任务
//	err = r.channel.QueueBind(r.QueueName, r.RoutingKey, r.ExchangeName, true, nil)
//	if err != nil {
//		fmt.Printf("绑定队列失败:%s \n", err)
//		return
//	}
//	// 获取消费通道,确保rabbitMQ一个一个发送消息
//	err = r.channel.Qos(1, 0, true)
//	msgList, err := r.channel.Consume(r.QueueName, "", false, false, false, false, nil)
//	if err != nil {
//		fmt.Printf("获取消费通道异常:%s \n", err)
//		return
//	}
//	for msg := range msgList {
//		// 处理数据
//		err := receiver.Consumer(msg.Body)
//		if err != nil {
//			err = msg.Ack(true)
//			if err != nil {
//				fmt.Printf("确认消息未完成异常:%s \n", err)
//				return
//			}
//		} else {
//			// 确认消息,必须为false
//			err = msg.Ack(false)
//			if err != nil {
//				fmt.Printf("确认消息完成异常:%s \n", err)
//				return
//			}
//			return
//		}
//	}
//}
//
//// 关闭RabbitMQ连接
//func (r *RabbitMQ) OnDestroy() {
//	// 先关闭管道,再关闭链接
//	err := r.channel.Close()
//	failOnError(err, "MQ管道关闭失败")
//
//	err = r.connection.Close()
//	failOnError(err, "MQ链接关闭失败")
//}
//
//func failOnError(err error, msg string) {
//	if err != nil {
//		fmt.Printf("%s: %s\n", msg, err)
//	}
//}
//
//func RaiseException(err error, msg interface{}) {
//	panic(fmt.Sprint("%s:%s", msg, err))
//}
